﻿#region

using System;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Linq;
using System.Linq.Expressions;

#endregion

namespace XXS.Common.BaseDataAccessLayer
{
    public interface IBaseDAL<T> : IDisposable where T : class
    {
        /// <summary>
        ///     创建模型 T
        /// </summary>
        /// <param name="model">模型 T</param>
        /// <param name="newId">是否生成新id</param>
        /// <param name="reloadModelFromDb">是否重新从数据库中读取数据,如果您需要级联数据加载,请设置为true</param>
        /// <returns>被操作的 T</returns>
        T Create(T model, bool newId = true, bool reloadModelFromDb = false);

        /// <summary>
        ///     删除模型 T
        /// </summary>
        /// <param name="model"></param>
        void Delete(T model);

        /// <summary>
        ///     更新模型 T
        /// </summary>
        /// <param name="model">模型 T</param>
        /// <param name="refreshUpdateTime"></param>
        /// <param name="reloadModelFromDb">是否重新从数据库中读取数据,如果您需要级联数据加载,请设置为true</param>
        /// <returns>被操作的 T</returns>
        T Update(T model, bool refreshUpdateTime = true, bool reloadModelFromDb = false);

        /// <summary>
        ///     查找一个模型 T
        /// </summary>
        /// <param name="id">key id</param>
        /// <returns></returns>
        T Find(object id);


        /// <summary>
        ///     在数据库中按照λ表达式查找一条记录,并返回
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        T Find(Expression<Func<T, bool>> predicate);


        /// <summary>
        ///     在数据库中按照λ表达式查找一条记录,并返回
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="includingStrings"></param>
        /// <returns></returns>
        T Find(Expression<Func<T, bool>> predicate,string[] includingStrings);

        /// <summary>
        ///     按照λ表达式获取记录集数量
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        int Count(Expression<Func<T, bool>> predicate);

        /// <summary>
        ///     按照λ表达式确认是否在数据库中存在
        /// </summary>
        /// <param name="anyLambda"></param>
        /// <returns></returns>
        bool Exist(Expression<Func<T, bool>> anyLambda);

        /// <summary>
        ///     按照λ表达式确认是否在数据库中存在
        /// </summary>
        /// <param name="anyLambda"></param>
        /// <returns></returns>
        bool NotExist(Expression<Func<T, bool>> anyLambda);


        /// <summary>
        ///     获取数据集列表
        /// </summary>
        /// <returns></returns>
        IQueryable<T> FindList();

        /// <summary>
        ///     获取数据集列表
        /// </summary>
        /// <param name="tracking">是否跟踪记录集</param>
        /// <param name="lazy">是否延迟加载</param>
        /// <returns></returns>
        IQueryable<T> FindList(bool tracking = true, bool lazy = true);

        /// <summary>
        ///     按照λ表达式获取数据集列表
        /// </summary>
        /// <param name="whereLamdba">where的λ表达式</param>
        /// <param name="includings">Including，导航属性</param>
        /// <param name="tracking">是否跟踪记录集</param>
        /// <param name="lazy">是否延迟加载</param>
        /// <returns></returns>
        IQueryable<T> FindList(Expression<Func<T, bool>> whereLamdba,
            string[] includings = null,
            bool tracking = true,
            bool lazy = true);

        /// <summary>
        ///     按照λ表达式获取数据集列表
        /// </summary>
        /// <param name="includings">Including，导航属性</param>
        /// <param name="tracking">是否跟踪记录集</param>
        /// <param name="lazy">是否延迟加载</param>
        /// <returns></returns>
        IQueryable<T> FindList(string[] includings = null,
            bool tracking = true,
            bool lazy = true);

        /// <summary>
        ///     按照λ表达式获取数据集分页列表
        /// </summary>
        /// <typeparam name="TS">排序类型</typeparam>
        /// <param name="whereLamdba">where的λ表达式</param>
        /// <param name="orderLamdba">orderby的λ表达式</param>
        /// <param name="isAsc">是否是否正序排列</param>
        /// <param name="pageIndex">分页页码</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="totalRecord">记录集总数</param>
        /// <returns></returns>
        IQueryable<T> FindPagenatedList<TS>(
            Expression<Func<T, bool>> whereLamdba,
            Expression<Func<T, TS>> orderLamdba,
            bool isAsc,
            int pageIndex,
            int pageSize,
            out int totalRecord);

        /// <summary>
        ///     在模型未持久化前,查找原始数据.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        DbPropertyValues FindOriginalValues(T model);

        /// <summary>
        ///     在模型未持久化前,查找当前数据.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        DbPropertyValues FindCurrentValues(T model);

        /// <summary>
        ///     获取模型校验错误
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        DbEntityValidationResult GetValidationErrors(T model);
    }
}